<template>
    <view>
        <view class="left_right_column_box">
            <view class="left_column">
                <scroll-view :style="{ height: viewHeight }" scroll-y="true" :scroll-top="scrollTop">
                    <view
                        v-for="item in titleContenData"
                        :key="item.id"
                        :class="{ left_column_for: true, activity: selectIndex == item.index ? true : false }"
                        @click="clickTitle(item)">
                        {{ item.title }}
                    </view>
                </scroll-view>
            </view>

            <view class="right_column">
                <scroll-view
                    :style="{ height: viewHeight }"
                    scroll-y="true"
                    :scroll-into-view="selectId"
                    scroll-with-animation="true"
                    @scroll="scroll">
                    <view
                        :id="item.id"
                        class="floorType right_title_content_for"
                        v-for="item in titleContenData"
                        :key="item.id">
                        <view class="right_title">{{ item.title }}</view>
                        <view v-for="items in item.contents" :key="items.id">{{ items.content }}</view>
                    </view>
                </scroll-view>
            </view>
        </view>
    </view>
</template>

<script>
// 防抖
let timer = undefined

export default {
    data() {
        return {
            // 屏幕高度
            viewHeight: null,
            // 源数据
            titleContenData: [],
            // 设置锚点
            selectId: "id1",
            // 设置高亮
            selectIndex: 0,
            // 设置左栏顶部距离
            scrollTop: 0,
        }
    },

    mounted() {
        let that = this
        uni.getSystemInfo({
            success: function ({ windowHeight }) {
                that.viewHeight = windowHeight + "px"
            },
        })

        // 创建数据
        that.createData()

        // 此处使用$nextTick是非常有必要
        // 官方建议
        // 实际测试如果不用会报错
    },

    methods: {
        // 滚动时触发
        scroll({ detail: { scrollTop } }) {
            let that = this,
                titleContenData = that.titleContenData

            // 防抖
            // timer定义在全局
            // 如果没有防抖会触发许多次
            // 对性能不友好
            if (timer !== undefined) clearTimeout(timer)

            timer = setTimeout(function () {
                // 当右侧滚动到顶部时强制赋值为0
                // 因为在滚动时一般获取到的数据是0-10的范围
                // 小概率会获取到0
                // 因为原先存储viewTop属性的第一个值就是0
                scrollTop = scrollTop < 10 ? 0 : scrollTop
                let selectIndex = titleContenData.findIndex((item) => item.viewTop >= scrollTop)

                // 设置高亮
                that.selectIndex = selectIndex
                that.$forceUpdate()
                // 此属性联动左侧滚动条
                // 当右侧滚动时
                // 左侧也会相应的滚动
                // 只是滚动的距离不一样
                that.scrollTop = 5 * that.selectIndex
            }, 70)
        },

        // 标题点击事件
        clickTitle({ id, index }) {
            // 设置锚点
            this.selectId = id
            // 设置高亮
            this.selectIndex = index
        },

        // 生成内容
        createContent(n) {
            let content = []
            for (let i = 0; i < n; i++)
                content.push({
                    id: i + 1,
                    content: `内容${i + 1}内容`,
                })
            return content
        },

        // 创建数据
        createData() {
            // 生成标题
            for (let i = 0; i < 24; i++)
                this.titleContenData.push({
                    // 因为需要绑定id作为锚点目标
                    // 所以不能以数字开头
                    id: `id${i + 1}`,
                    index: i,
                    title: "标题" + (i + 1),
                    contents: this.createContent(parseInt(Math.random() * 24 + 1, 10)),
                })
            let that = this
            setTimeout(function () {
                const query = uni.createSelectorQuery().in(that)

                query
                    .selectAll(".floorType")
                    .boundingClientRect((VNodeAll) => {
                        VNodeAll.forEach(({ top }, i) => {
                            // 获取并存储每个视图到顶部的距离
                            that.titleContenData[i].viewTop = top
                        })
                    })
                    .exec()
            }, 1000)
        },
    },
}
</script>

<style lang="scss">
/* 公共样式 */
.left_right_column_box {
    width: 100%;
    display: flex;
    justify-content: space-evenly;
}

/* 左侧样式 */
.left_column {
    flex: 1;
}

.left_column_for {
    text-align: center;
    padding: 10rpx 0;
}

.activity {
    color: #000fff;
}

/* 右侧样式 */
.right_column {
    flex: 3;
    margin-left: 36rpx;
}

.right_title_content_for {
    margin-top: 36rpx;
}

.right_title_content_for:first-child {
    margin-top: 0;
}

.right_title {
    font-weight: 700;
}

/* 隐藏scroll-wiew元素的滚动条 */
scroll-view ::-webkit-scrollbar {
    width: 0;
    height: 0;
    background-color: transparent;
}
</style>
